package com.runssnail.huafeiduo.api.common;

import com.runssnail.huafeiduo.api.internal.utils.MD5Util;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * Created by zhengwei on 2016/3/17.
 */
public class SignUtils {

    private static final Log log = LogFactory.getLog(SignUtils.class);

    public static final String  DEFAULT_CHARSET = "UTF-8";

    /**
     * 生成随机字符串
     *
     * @param charset 字符集
     * @return 随机字符串
     */
    public static String buildNonce(String charset) {
        Random random = new Random();
        return MD5Util.MD5Encode(String.valueOf(random.nextInt(10000)), charset); // "UTF-8"
    }

    /**
     * 生成随机字符串
     *
     * @return 随机字符串
     */
    public static String buildNonce() {
        return buildNonce(DEFAULT_CHARSET);
    }

    /**
     * 生成sign
     *
     * @param params 参数
     * @param key    签名密钥
     * @return 签名
     */
    public static String buildSign(Map<String, Object> params, String key) {

        return buildSign(params, key, SignType.MD5);

    }

    /**
     * 生成签名sign
     *
     * @param params   参数
     * @param key      签名密钥
     * @param signType 签名方式
     * @return
     */
    public static String buildSign(Map<String, Object> params, String key, SignType signType) {
        if (log.isDebugEnabled()) {
            log.debug("genSign, params=" + params + ", signType=" + signType);
        }

        String paramsStr = buildUrlParamsStr(params, null);

        paramsStr += key;

//        System.out.println(paramsStr);

        String sign = null;
        if (signType.isMd5()) {
            sign = DigestUtils.md5Hex(paramsStr).toLowerCase();
        } else if (signType.isSHA1()) {
            sign = DigestUtils.sha1Hex(paramsStr).toLowerCase();
        } else if (signType.isRsa()) {
            //
            throw new UnsupportedOperationException("unsupport current sign type, signType=" + signType);
        }

        if (log.isDebugEnabled()) {
            log.debug("genSign, sign=" + sign);
        }
//        System.out.println(sign);

        return sign;
    }

    public static String buildUrlParamsStr(Map<String, Object> packageParams, String charset) {
        StringBuilder sb = new StringBuilder();
        Set<Map.Entry<String, Object>> es = packageParams.entrySet();
        for (Map.Entry<String, Object> entry : es) {
            String k = entry.getKey();
            Object v = entry.getValue();
            if (StringUtils.isNotBlank(charset) && v != null) {
                v = urlEncode(v.toString(), charset);
            }
            sb.append(k).append(v);
        }

        return sb.toString();
    }

    // 特殊字符处理
    private static String urlEncode(String src, String charset) {
        String str = null;
        try {
            str = URLEncoder.encode(src, charset).replace("+", "%20");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("URLEncoder error, charset=" + charset, e);
        }
        return str;

    }
}
